
package com.dream.utils.date;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateUtils;

import com.dream.utils.exception.BusinessException;

/**
 * populate a date from  String to Date
 * @copyright evan
 * @author evan
 * @Revision
 * @date 2012/8/18
 */
public final class DateParseUtils {

	/** The Constant DEFAULT_DATE_FORMAT. */
	public  static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
	
	/** date format without any delimiter */
	public static final String DATE_FORAMT_WITHOUT_DELIMITER ="yyyyMMdd";

	/** The Constant DATE_FORMAT2. */
	public static final String DATE_FORMAT2 = "yyyy/MM/dd";

	public static final String DATE_YYYY_MM = "yyyy-MM";

	/** The Constant DEFAULT_DATE_FORMAT_FULL. */
	public static final String DEFAULT_DATE_FORMAT_HOU = "yyyy-MM-dd HH";
	public static final String DEFAULT_DATE_FORMAT_MIN = "yyyy-MM-dd HH:mm";
	public static final String DEFAULT_DATE_FORMAT_FULL_SEC = "yyyy-MM-dd HH:mm:ss";
	public static final String DEFAULT_DATE_FORMAT_FULL_MILL = "yyyy-MM-dd HH:mm:ss SSS";
	
	private static final String DATE_SPLIT = "(-)|(/)";
	
	/**
	 * Parses String date to Date date( '/' or '-' as split)
	 * 
	 * @param dateStr string date
	 *            
	 * @return the date
	 */
	public static Date parseDate(String dateStr) {
			String[] defFormats = new String[] { DEFAULT_DATE_FORMAT, DATE_FORMAT2, DEFAULT_DATE_FORMAT_HOU,DEFAULT_DATE_FORMAT_MIN,DEFAULT_DATE_FORMAT_FULL_SEC,DEFAULT_DATE_FORMAT_FULL_MILL, DATE_YYYY_MM ,DATE_FORAMT_WITHOUT_DELIMITER};
			return parse(dateStr,DATE_SPLIT,defFormats);
	}
	
	
	/**
	 * 
	 * @author evan
	 * @Revision
	 * @date 2014-2-8
	 * @param dateStr
	 * @return
	 */
	public static Date parseDateWithNull(String dateStr){
		
		if(StringUtils.isEmpty(dateStr))
			return null;
		return parseDate(dateStr);
	}
	
	/**
	 * parse date by format
	 * @param dateStr
	 * @param splits
	 * @param formats
	 * @return
	 */
	private static Date parse(String dateStr,String splits,String[] formats){
		
		if (StringUtils.isBlank(dateStr)) {
			throw new BusinessException("date is nul or blank");
		}
		
		Calendar cal = Calendar.getInstance();
		Date toDate = null;
		try {
			toDate = DateUtils.parseDate(dateStr, formats);
			cal.setTime(toDate);
		}catch (ParseException e) {
			throw new BusinessException("date is not date formate");
		}
		
		int year = cal.get(Calendar.YEAR);
		int month = cal.get(Calendar.MONTH) + 1;
		int year2 = year;
		int month2 = month;
		
		if(StringUtils.isNotBlank(splits)){
			String[] ss = dateStr.split(splits);
			if(null == ss || ss.length <2){
				throw new BusinessException("date format is illegal");
			}
			try{
				year2 = Integer.valueOf(ss[0]);
				month2 = Integer.valueOf(ss[1]);
			}catch(NumberFormatException e){
				throw new BusinessException("date numberic only");
			}
		}
		
		if (year != year2 || month != month2) {
			throw new BusinessException("date is illegal ");
		}
		
		return toDate;
	}
	/**
	 * Parses some special day
	 * pattern yyyyMMdd split is null
	 * @param dateStr  the date str
	 *           
	 * @param pattern the pattern
	 *            
	 * @return the date
	 */
	public static Date parseDate(String dateStr, String pattern,String split) {
		return parse(dateStr,split,new String[] { pattern });
	}
	
	/**
	 * 
	 * @param dateStr
	 * @param patterns
	 * @param split
	 * @return
	 */
	public static Date parseDate(String dateStr, String[] patterns, String split) {
		return parse(dateStr, split, patterns);
	}

	/**
	 * judge is a legal date String
	 * 
	 * @param dateStr the date str
	 *            
	 * @return isDate
	 */
	public static boolean isDateString(String dateStr) {

		boolean isDate = true;
		try {
			parseDate(dateStr);
		} catch (Exception e) {
			isDate = false;
		}
		return isDate;
	}

	/**
	 * Parses the full date. DEFAULT_DATE_FORMAT_FULL = "yyyy-MM-dd HH:mm:ss";
	 * 
	 * @param dateStr the date str
	 *            
	 * @return the date
	 */
	public static Date parseFullDate(String dateStr) {

		return parseDate(dateStr, DEFAULT_DATE_FORMAT_FULL_SEC,"-");
	}

	/**
	 * Time abstract.
	 * 
	 * @param date the date
	 *            
	 * @return the string
	 */
	public static String timeAbstract(Date date) {
		return format(date, "HH:mm");
	}

	/**
	 * Format.
	 * 
	 * @param date  the date
	 *           
	 * @return the string
	 */
	public static String format(Date date) {
		return format(date, "yyyyMMdd_HHmm");
	}

	/**
	 * Format short.
	 * 
	 * @param date the date
	 *            
	 * @return the string
	 */
	public static String formatShort(Date date) {
		return format(date, DEFAULT_DATE_FORMAT);
	}

	/**
	 * Format long.
	 * 
	 * @param date the date
	 *            
	 * @return the string
	 */
	public static String formatLong(Date date) {
		return format(date, DEFAULT_DATE_FORMAT_FULL_SEC);
	}

	/**
	 * Format.
	 * 
	 * @param date the date
	 *            
	 * @param pattern the pattern
	 *            
	 * @return the string
	 */
	public static String format(Date date, String pattern) {
		SimpleDateFormat sdf = new SimpleDateFormat(pattern);
		return sdf.format(date);
	}
	
	public static Date parseWitTime(String date,String timeWithPM){
		
		if(StringUtils.isEmpty(date) || StringUtils.isEmpty(timeWithPM)){
			return null;
		}
		StringBuilder builder = new StringBuilder(date);
		builder.append(" ");
		String left = timeWithPM.substring(0, timeWithPM.length()-3);
		String[] arr = left.split(":");
		if(timeWithPM.endsWith("PM")){
			int hour = Integer.valueOf(arr[0]) + 12;
			left = String.valueOf(hour).concat(":").concat(arr[1]);
		}
		builder.append(left);
		builder.append(":00");
		
		return parseDate(builder.toString());
	}
}
